#ifndef TEXTUREMANAGER_H
#define TEXTUREMANAGER_H

#include "Texture2D.h"
#include "TextureCube.h"
#include "RenderTarget.h"
#include "ResourceManager.h"

namespace Cvekas {

/// Texture Manager
class TextureManager : public ResourceManager<TexturePtr>
{
public:
	/// Constructor
	TextureManager(D3DDevicePtr device);
	
	/// Destructor
	virtual ~TextureManager();

	/// Loads new texture from file
	/// \param name Texture name
	/// \param file Texture filename
	/// \param format Surfacea format
	/// \param pow_of2 Should texture be rounded to the nearest power-of-2 size?
	/// \param lockable Will the texture be lockable?
	/// \param gen_mipmaps Should engine generate mipmap chain?
	Texture2DPtr loadTexture2D(const std::string& name, const std::string& file, 
		D3DFORMAT format = D3DFMT_FROM_FILE, bool pow_of2 = false, bool lockable = false, bool gen_mipmaps = true);

	/// Creates new texture
	/// \param name Texture name
	/// \param width Width in pixels
	/// \param height Height in pixels
	/// \param format Surface format
	/// \param mipmaped Will texture have mipmaps?
	/// \param dynamic Will texture be dynamic?
	Texture2DPtr createTexture2D(const std::string& name, uint width, uint height, 
		D3DFORMAT format, bool mipmaped = false, bool dynamic = false);

	/// Loads cube map from ddf file
	/// \param name Texture name
	/// \param file Texture filename
	TextureCubePtr loadTextureCube(const std::string& name, const std::string& file);

	/// Creates new render target
	/// \param name Render target name
	/// \param width Width in pixels
	/// \param height Height in pixels
	/// \param format Surface format
	RenderTargetPtr createRenderTarget(const std::string& name, uint width, uint height,
		D3DFORMAT format);
	
	/// Returns existing texture
	/// \param name Texture name
	Texture2DPtr getTexture2D(const std::string& name);
	
	/// Returns existing texture
	/// \param id Texture ID
	Texture2DPtr getTexture2D(ResourceId id);

	/// Returns existing cube texture
	/// \param name Texture name
	TextureCubePtr getTextureCube(const std::string& name);
	
	/// Returns existing cube texture
	/// \param id Texture ID
	TextureCubePtr getTextureCube(ResourceId id);

	/// Returns existing render target
	/// \param name Render target name
	RenderTargetPtr getRenderTarget(const std::string& name);
	
	/// Returns existing render target
	/// \param id Render target ID
	RenderTargetPtr getRenderTarget(ResourceId id);

	/// You shouldn't call this
	void onDeviceLost();
	/// You shouldn't call this
	void onDeviceReset();

private:
	D3DDevicePtr device;
};

typedef boost::shared_ptr<TextureManager> TextureManagerPtr;

}

#endif